/*
 * Store.hpp
 *
 *  Created on: Oct 8, 2013
 *      Author: z1083248
 */

#ifndef STORE_HPP_
#define STORE_HPP_

#include "Data.hpp"
#include "Container.hpp"
#include "Lock.hpp"
#include <boost/unordered_map.hpp>
#include <boost/array.hpp>
#include <string>
#include <cassert>

namespace datastore
{

template<typename Locker, unsigned int store_count>
class Store
{
public:
   static Store* instance()
   {
      static Store object;
      return &object;
   }

   typedef boost::unordered_map<std::string, Container *> Data;

   template<typename T>
   void get(std::string name, T &value)
   {
      Lock<Locker> lock(locker_);
      Data::iterator i(data_.find(name));
      assert(i != data_.end());
      i->second->get(value);
   }

   template<typename T>
   void set(std::string name, const T &data)
   {
      Lock<Locker> lock(locker_);
      Data::iterator i(data_.find(name));
      if (i != data_.end())
      {
         i->second->set(data);
      }
      else
      {
         insert(name, data);
      }
   }

   template<typename T>
   void insert(std::string name, const T &data)
   {
      Lock<Locker> lock(locker_);
      assert(index_ < store_count);
      data_[name] = containers.at(index_++) = T(data); //new Container(T(data));
   }

private:
   Store() :
         index_(0)
   {
   }

   unsigned int index_;
   Data data_;
   Locker locker_;
   boost::array<Container, store_count> containers;
};

}

#endif /* STORE_HPP_ */
